#pragma once

// Forward declarations
class ContourDot;
class Stroke;

////////////////////////////////////////////////////////////////////////////////////
// The purpose of this class is reducing the number of iterations for
// searching the neighbor contour dots (distance < distanceCriterion).
// The alternative nested loop:
//		for (stroke1...) { for (stroke2..) { if (d < dMax) {do something;} }}
// is very slow, because it requires millions of iterations for thousands of strokes.

class NeighborEnumerator
{
public:
	struct Info 
	{
		const ContourDot* dot;
		const Stroke* stroke;
		int strokeEnd;
	};

	NeighborEnumerator(float maxX, float maxY, float distanceCriterion, int capacity);
	~NeighborEnumerator();

	void Add(const ContourDot&, const Stroke*, int strokeEnd);
	bool SelectNeighbors(const ContourDot&, bool avoidRepeatingPairs = true);
	const Info* FindNextNeighbor();
	const Info* GetInfoForStrokeEnd(const Stroke*, int strokeEnd) const;
	float GetDistanceCriterion() const;

private:
	void GetCoordinates(const ContourDot*, int& outX, int& outY) const;

private:
	struct Node { Info info; int nextIndex; bool isSelfVisited; };

	// data
	int mWidth, mHeight;
	float mDistanceCriterion, mDistanceCriterionSquared;

	int* mListHeads;
	Node* mNodes;

	// the index just behind the free node
	int mFreeNodeIndex;
	
	const ContourDot* mCurrentDot;
	int mCurrentIndexSelection[9];
	int mCurrentSelection, mCurrentIndex;
	bool mAvoidRepeatingPairs;
};

